home *** CD-ROM | disk | FTP | other *** search
/ Enter 2006 September / Enter 09 2006.iso / Internet / SpamExperts Home 1.1 / SpamExperts Home.exe / lib / spamexperts.modules / spambayes / FileCorpus.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2006-07-14  |  11.2 KB  |  323 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.4)
  3.  
  4. '''FileCorpus.py - Corpus composed of file system artifacts
  5.  
  6. Classes:
  7.     FileCorpus - an observable dictionary of FileMessages
  8.     ExpiryFileCorpus - a FileCorpus of young files
  9.     FileMessage - a subject of Spambayes training
  10.     FileMessageFactory - a factory to create FileMessage objects
  11.     GzipFileMessage - A FileMessage zipped for less storage
  12.     GzipFileMessageFactory - factory to create GzipFileMessage objects
  13.  
  14. Abstract:
  15.     These classes are concrete implementations of the Corpus framework.
  16.  
  17.     FileCorpus is designed to manage corpora that are directories of
  18.     message files.
  19.  
  20.     ExpiryFileCorpus is an ExpiryCorpus of file messages.
  21.  
  22.     FileMessage manages messages that are files in the file system.
  23.  
  24.     FileMessageFactory is responsible for the creation of FileMessages,
  25.     in response to requests to a corpus for messages.
  26.  
  27.     GzipFileMessage and GzipFileMessageFactory are used to persist messages
  28.     as zipped files.  This can save a bit of persistent storage, though the
  29.     ability of the compresser to do very much deflation is limited due to the
  30.     relatively small size of the average textual message.  Still, for a large
  31.     corpus, this could amount to a significant space savings.
  32.  
  33.     See Corpus.__doc__ for more information.
  34.  
  35. To Do:
  36.     o Suggestions?
  37. '''
  38. from __future__ import generators
  39. __author__ = 'Tim Stone <tim@fourstonesExpressions.com>'
  40. __credits__ = 'Richie Hindle, Tim Peters, all the spambayes contributors.'
  41. import email
  42. from spambayes import Corpus
  43. from spambayes import message
  44. from spambayes import storage
  45. import sys
  46. import os
  47. import gzip
  48. import fnmatch
  49. import getopt
  50. import time
  51. import stat
  52. from spambayes.Options import options
  53.  
  54. class FileCorpus(Corpus.Corpus):
  55.     
  56.     def __init__(self, factory, directory, filter = '*', cacheSize = 250):
  57.         '''Constructor(FileMessageFactory, corpus directory name, fnmatch
  58. filter'''
  59.         Corpus.Corpus.__init__(self, factory, cacheSize)
  60.         self.directory = directory
  61.         self.filter = filter
  62.         for filename in os.listdir(directory):
  63.             if fnmatch.fnmatch(filename, filter):
  64.                 self.msgs[filename] = None
  65.                 continue
  66.         
  67.  
  68.     
  69.     def makeMessage(self, key, content = None):
  70.         '''Ask our factory to make a Message'''
  71.         msg = self.factory.create(key, self.directory, content)
  72.         return msg
  73.  
  74.     
  75.     def addMessage(self, message, observer_flags = 0):
  76.         '''Add a Message to this corpus'''
  77.         if not fnmatch.fnmatch(message.key(), self.filter):
  78.             raise ValueError
  79.         
  80.         if options[('globals', 'verbose')]:
  81.             print 'adding', message.key(), 'to corpus'
  82.         
  83.         message.directory = self.directory
  84.         message.store()
  85.         Corpus.Corpus.addMessage(self, message, observer_flags)
  86.  
  87.     
  88.     def removeMessage(self, message, observer_flags = 0):
  89.         '''Remove a Message from this corpus'''
  90.         if options[('globals', 'verbose')]:
  91.             print 'removing', message.key(), 'from corpus'
  92.         
  93.         message.remove()
  94.         Corpus.Corpus.removeMessage(self, message, observer_flags)
  95.  
  96.     
  97.     def __repr__(self):
  98.         '''Instance as a representative string'''
  99.         nummsgs = len(self.msgs)
  100.         if nummsgs != 1:
  101.             s = 's'
  102.         else:
  103.             s = ''
  104.         if options[('globals', 'verbose')] and nummsgs > 0:
  105.             lst = ', ' + '%s' % self.keys()
  106.         else:
  107.             lst = ''
  108.         return '<%s object at %8.8x, directory: %s, %s message%s%s>' % (self.__class__.__name__, id(self), self.directory, nummsgs, s, lst)
  109.  
  110.  
  111.  
  112. class ExpiryFileCorpus(Corpus.ExpiryCorpus, FileCorpus):
  113.     '''FileCorpus of "young" file system artifacts'''
  114.     
  115.     def __init__(self, expireBefore, factory, directory, filter = '*', cacheSize = 250):
  116.         '''Constructor(FileMessageFactory, corpus directory name, fnmatch
  117. filter'''
  118.         Corpus.ExpiryCorpus.__init__(self, expireBefore)
  119.         FileCorpus.__init__(self, factory, directory, filter, cacheSize)
  120.  
  121.  
  122.  
  123. class FileMessage(object):
  124.     '''Message that persists as a file system artifact.'''
  125.     message_class = message.SBHeaderMessage
  126.     
  127.     def __init__(self, file_name = None, directory = None):
  128.         '''Constructor(message file name, corpus directory name)'''
  129.         self.file_name = file_name
  130.         self.directory = directory
  131.         self.loaded = False
  132.         self._msg = self.message_class()
  133.  
  134.     
  135.     def __getattr__(self, att):
  136.         '''Pretend we are a subclass of message.SBHeaderMessage.'''
  137.         if hasattr(self, '_msg') and hasattr(self._msg, att):
  138.             return getattr(self._msg, att)
  139.         
  140.         raise AttributeError()
  141.  
  142.     
  143.     def __getitem__(self, k):
  144.         '''Pretend we are a subclass of message.SBHeaderMessage.'''
  145.         if hasattr(self, '_msg'):
  146.             return self._msg[k]
  147.         
  148.         raise TypeError()
  149.  
  150.     
  151.     def __setitem__(self, k, v):
  152.         '''Pretend we are a subclass of message.SBHeaderMessage.'''
  153.         if hasattr(self, '_msg'):
  154.             self._msg[k] = v
  155.             return None
  156.         
  157.         raise TypeError()
  158.  
  159.     
  160.     def as_string(self, unixfrom = False):
  161.         self.load()
  162.         return self._msg.as_string(unixfrom)
  163.  
  164.     
  165.     def pathname(self):
  166.         '''Derive the pathname of the message file'''
  167.         if not self.file_name is not None:
  168.             raise AssertionError, 'Must set filename before using FileMessage instances.'
  169.         if not self.directory is not None:
  170.             raise AssertionError, 'Must set directory before using FileMessage instances.'
  171.         return os.path.join(self.directory, self.file_name)
  172.  
  173.     
  174.     def load(self):
  175.         '''Read the Message substance from the file'''
  176.         if self.loaded:
  177.             return None
  178.         
  179.         if not self.file_name is not None:
  180.             raise AssertionError, 'Must set filename before using FileMessage instances.'
  181.         if options[('globals', 'verbose')]:
  182.             print 'loading', self.file_name
  183.         
  184.         pn = self.pathname()
  185.         fp = gzip.open(pn, 'rb')
  186.         
  187.         try:
  188.             self._msg = email.message_from_string(fp.read(), _class = self.message_class)
  189.         except IOError:
  190.             e = None
  191.             if str(e) == 'Not a gzipped file' or str(e) == 'Unknown compression method':
  192.                 fp.close()
  193.                 fp = open(self.pathname(), 'rb')
  194.                 self._msg = email.message_from_string(fp.read(), _class = self.message_class)
  195.                 fp.close()
  196.             else:
  197.                 raise 
  198.         except:
  199.             str(e) == 'Unknown compression method'
  200.  
  201.         fp.close()
  202.         self.loaded = True
  203.  
  204.     
  205.     def store(self):
  206.         '''Write the Message substance to the file'''
  207.         if not self.file_name is not None:
  208.             raise AssertionError, 'Must set filename before using FileMessage instances.'
  209.         if options[('globals', 'verbose')]:
  210.             print 'storing', self.file_name
  211.         
  212.         fp = open(self.pathname(), 'wb')
  213.         fp.write(self.as_string())
  214.         fp.close()
  215.  
  216.     
  217.     def remove(self):
  218.         '''Message hara-kiri'''
  219.         if options[('globals', 'verbose')]:
  220.             print 'physically deleting file', self.pathname()
  221.         
  222.         
  223.         try:
  224.             os.unlink(self.pathname())
  225.         except OSError:
  226.             if options[('globals', 'verbose')]:
  227.                 print 'file', self.pathname(), 'can not be deleted'
  228.             
  229.         except:
  230.             options[('globals', 'verbose')]
  231.  
  232.  
  233.     
  234.     def name(self):
  235.         '''A unique name for the message'''
  236.         if not self.file_name is not None:
  237.             raise AssertionError, 'Must set filename before using FileMessage instances.'
  238.         return self.file_name
  239.  
  240.     
  241.     def key(self):
  242.         '''The key of this message in the msgs dictionary'''
  243.         if not self.file_name is not None:
  244.             raise AssertionError, 'Must set filename before using FileMessage instances.'
  245.         return self.file_name
  246.  
  247.     
  248.     def __repr__(self):
  249.         '''Instance as a representative string'''
  250.         sub = self.as_string()
  251.         if not options[('globals', 'verbose')]:
  252.             if len(sub) > 20:
  253.                 if len(sub) > 40:
  254.                     sub = sub[:20] + '...' + sub[-20:]
  255.                 else:
  256.                     sub = sub[:20]
  257.             
  258.         
  259.         return '<%s object at %8.8x, file: %s, %s>' % (self.__class__.__name__, id(self), self.pathname(), sub)
  260.  
  261.     
  262.     def __str__(self):
  263.         '''Instance as a printable string'''
  264.         return self.__repr__()
  265.  
  266.     
  267.     def createTimestamp(self):
  268.         '''Return the create timestamp for the file'''
  269.         
  270.         try:
  271.             stats = os.stat(self.pathname())
  272.         except OSError:
  273.             ctime = time.time()
  274.  
  275.         ctime = stats[stat.ST_CTIME]
  276.         return ctime
  277.  
  278.  
  279.  
  280. class MessageFactory(Corpus.MessageFactory):
  281.     klass = None
  282.     
  283.     def create(self, key, directory, content = None):
  284.         '''Create a message object from a filename in a directory'''
  285.         if content:
  286.             msg = email.message_from_string(content, _class = self.klass)
  287.             msg.file_name = key
  288.             msg.directory = directory
  289.             msg.loaded = True
  290.             return msg
  291.         
  292.         return self.klass(key, directory)
  293.  
  294.  
  295.  
  296. class FileMessageFactory(MessageFactory):
  297.     '''MessageFactory for FileMessage objects'''
  298.     klass = FileMessage
  299.  
  300.  
  301. class GzipFileMessage(FileMessage):
  302.     '''Message that persists as a zipped file system artifact.'''
  303.     
  304.     def store(self):
  305.         '''Write the Message substance to the file'''
  306.         if not self.file_name is not None:
  307.             raise AssertionError, 'Must set filename before using FileMessage instances.'
  308.         if options[('globals', 'verbose')]:
  309.             print 'storing', self.file_name
  310.         
  311.         pn = self.pathname()
  312.         gz = gzip.open(pn, 'wb')
  313.         gz.write(self.as_string())
  314.         gz.flush()
  315.         gz.close()
  316.  
  317.  
  318.  
  319. class GzipFileMessageFactory(MessageFactory):
  320.     '''MessageFactory for FileMessage objects'''
  321.     klass = GzipFileMessage
  322.  
  323.